//
//  XFYInnervationView.m
//  SDKSample
//
//  Created by 小肥羊 on 15/12/15.
//  Copyright © 2015年 Zhu‘s Game House. All rights reserved.
//

#import "XFYInnervationView.h"
#import <CoreMotion/CoreMotion.h>

static const CGFloat XFYInnervationRotationMinimumTreshold = 0.6f;       /**< 敏感度 */
static const CGFloat XFYInnervationUpdateInterval = 1 / 100;             /**< 更新间隔 */
static const CGFloat XFYInnervationRotationFactor = 0.4f;                /**< 移动速度 */

@interface XFYInnervationView ()

@property (nonatomic, assign) CGRect viewFrame;

@property (nonatomic, strong) CMMotionManager *motionManager;
@property (nonatomic, strong) UIScrollView *scrollView;

@property (nonatomic, assign) CGFloat motionRate;
@property (nonatomic, assign) NSInteger minimumXOffset;
@property (nonatomic, assign) NSInteger maximumXOffset;
@property (nonatomic, assign) NSInteger minimumYOffset;
@property (nonatomic, assign) NSInteger maximumYOffset;


@end

@implementation XFYInnervationView
#pragma mark - 初始化
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.viewFrame = frame;
        [self initValue];
    }
    return self;
}

- (void)initValue
{
    self.motionManager = [[CMMotionManager alloc] init];
    self.motionManager.gyroUpdateInterval = XFYInnervationUpdateInterval;
    
    self.scrollView = [[UIScrollView alloc] initWithFrame:(CGRect){CGPointZero,self.viewFrame.size}];
    [self.scrollView setUserInteractionEnabled:NO];
    [self.scrollView setBounces:NO];
    [self.scrollView setShowsHorizontalScrollIndicator:NO];
    [self.scrollView setShowsVerticalScrollIndicator:NO];
    [self.scrollView setContentSize:CGSizeZero];
    [self addSubview:self.scrollView];
    
    self.minimumXOffset = 0;
    self.minimumYOffset = 0;
    self.motionEnabled = YES;
}

#pragma mark - Set属性
- (void)setContentView:(UIView *)contentView
{
    _contentView = contentView;
    [_contentView setFrame:(CGRect){CGPointZero,CGSizeMake(self.viewFrame.size.width + 32, self.viewFrame.size.height + 32)}];
    [self.scrollView addSubview:_contentView];
    self.scrollView.contentSize = _contentView.bounds.size;
    self.scrollView.contentOffset = CGPointMake(16, 16);
    self.motionRate = _contentView.frame.size.width / self.viewFrame.size.width * XFYInnervationRotationFactor;
    self.maximumXOffset = self.scrollView.contentSize.width - self.scrollView.frame.size.width;
    self.maximumYOffset = self.scrollView.contentSize.height - self.scrollView.frame.size.height;
}
- (void)setMotionEnabled:(BOOL)motionEnabled
{
    _motionEnabled = motionEnabled;
    if (_motionEnabled) {
        [self startMonitoring];
    } else {
        [self stopMonitoring];
    }
}

#pragma mark - Core Motion
- (void)startMonitoring
{
    if (![self.motionManager isGyroActive] && [self.motionManager isGyroAvailable]) {
        [self.motionManager startGyroUpdatesToQueue:[NSOperationQueue currentQueue]
                                        withHandler:^(CMGyroData *gyroData, NSError *error) {
                                            CGFloat rotationRateX = gyroData.rotationRate.y;
                                            CGFloat rotationRateY = gyroData.rotationRate.x;
                                            if (fabs(rotationRateX) >= XFYInnervationRotationMinimumTreshold || fabs(rotationRateY) >= XFYInnervationRotationMinimumTreshold) {
                                                CGFloat offsetX;
                                                if (fabs(rotationRateX) >= XFYInnervationRotationMinimumTreshold) {
                                                    offsetX = self.scrollView.contentOffset.x + rotationRateX * self.motionRate;
                                                    if (offsetX > self.maximumXOffset) {
                                                        offsetX = self.maximumXOffset;
                                                    } else if (offsetX < self.minimumXOffset) {
                                                        offsetX = self.minimumXOffset;
                                                    }
                                                } else {
                                                    offsetX = self.scrollView.contentOffset.x;
                                                }
                                                CGFloat offsetY;
                                                if (fabs(rotationRateY) >= XFYInnervationRotationMinimumTreshold) {
                                                    offsetY = self.scrollView.contentOffset.y + rotationRateY * self.motionRate;
                                                    if (offsetY > self.maximumYOffset) {
                                                        offsetY = self.maximumYOffset;
                                                    } else if (offsetY < self.minimumYOffset) {
                                                        offsetY = self.minimumYOffset;
                                                    }
                                                } else {
                                                    offsetY = self.scrollView.contentOffset.y;
                                                }
                                                [UIView animateWithDuration:0.3f
                                                                      delay:0.0f
                                                                    options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionCurveEaseOut
                                                                 animations:^{
                                                                     [self.scrollView setContentOffset:CGPointMake(offsetX, offsetY) animated:NO];
                                                                 }
                                                                 completion:nil];
                                            }
                                        }];
    } else {
        NSLog(@"There is not available gyro.");
    }
}

- (void)stopMonitoring
{
    [self.motionManager stopGyroUpdates];
}



/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/

@end
